﻿#region Copyright and License Notice
// Copyright (C)2010-2016 - Rob Levine and other contributors
// http://configgen.codeplex.com
// 
// This file is part of ConfigGen.
// 
// ConfigGen is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// ConfigGen is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License and 
// the GNU Lesser General Public License along with ConfigGen.  
// If not, see <http://www.gnu.org/licenses/>
#endregion

using System.Xml;

namespace ConfigGen.Core.ConfigurationSettings
{
    /// <summary>
    /// Extension methods for serialising configuration classes into "seachable" xml. Searchable xml is an xml format designed to aid searching by XPath rather 
    /// than being semantically correct, or keeping a careful seperation between document meaning and markup.
    /// For instance, key/value pairs may be expressed as the key being the element name, and the value being the contents.
    /// </summary>
    public class SearchableXmlConverter : ISearchableXmlConverter
    {
        /// <summary>
        /// Serialises the instance to "searchable" xml, writing this to the supplied writer.
        /// </summary>
        /// <param name="machinesConfigurationCollection">Instance to serialise to "searchable" xml.</param>
        /// <param name="xmlWriter">Writer onto which to serialise the supplied instance.</param>
        public void ToSearchableXml(MachinesConfigurationCollection machinesConfigurationCollection, XmlWriter xmlWriter)
        {
            xmlWriter.WriteStartElement("MachineConfigurationRoot");
            xmlWriter.WriteStartElement("Machines");
            foreach (var machine in machinesConfigurationCollection.MachineConfigurationSettings)
            {
                ToSearchableXml(machine, xmlWriter);
            }
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();
        }

        /// <summary>
        /// Serialises the instance to "searchable" xml, writing this to the supplied writer.
        /// </summary>
        /// <param name="machineConfigurationSettings">Instance to serialise to "searchable" xml.</param>
        /// <param name="xmlWriter">Writer onto which to serialise the supplied instance.</param>
        public void ToSearchableXml(MachineConfigurationSettings machineConfigurationSettings, XmlWriter xmlWriter)
        {
            xmlWriter.WriteStartElement("Machine");
            xmlWriter.WriteAttributeString("name", machineConfigurationSettings.MachineName);
            xmlWriter.WriteAttributeString("configFilePath", machineConfigurationSettings.ConfigFilePath);
            xmlWriter.WriteStartElement("Values");
            foreach (var setting in machineConfigurationSettings.ConfigurationSettings)
            {
                ToSearchableXml(setting, xmlWriter);
            }
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();
        }

        /// <summary>
        /// Serialises the instance to "searchable" xml, writing this to the supplied writer. If the value of this setting is null, nothing is written.
        /// </summary>
        /// <param name="configurationSetting">Instance to serialise to "searchable" xml.</param>
        /// <param name="xmlWriter">Writer onto which to serialise the supplied instance.</param>
        public void ToSearchableXml(ConfigurationSetting configurationSetting, XmlWriter xmlWriter)
        {
            if (configurationSetting.Value != null)
            {
                xmlWriter.WriteElementString(configurationSetting.Token, configurationSetting.Value);
            }
        }
    }
}
